#
#    Pixel War (Server) - Server de Juego Multiplayer Online
#    Copyright (C) 2010 - Francisco Rivera
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import threading, select, socket
from protocolo import Protocolo
from handlers import HandlerCriaturas, HandlerId

DEBUG = False

class Conexion:

    PUERTO = 20000
    MAX_CONEXIONES = 20

    # Esta clase contiene el socket padre.

    def __init__(self):
        # creamos el socket padre
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # Comenzamos la escucha
        self.server.bind(('', Conexion.PUERTO))
        # Conexiones simultaneas maximas
        self.server.listen(Conexion.MAX_CONEXIONES)
        # handler ids
        self.hd = HandlerId()
        print 'Server en escucha'
        self.recibir()
        
    def recibir(self):
        while True:
            (sread, swrite, sexc) = select.select([self.server], [], [])
            for cliente in sread:
                if cliente == self.server:
                    socket, direccion = self.server.accept()                    
                    c = Cliente(socket, direccion, self.hd.getSiguienteId())
                    print "<--- %s ha entrado" % c.direccion


class Cliente(threading.Thread):

    ''' Clase para manejar los sockets hijos conectados con los clientes.'''
    
    def __init__(self, socket, direccion, id):
        threading.Thread.__init__(self)
        self.socket = socket
        self.direccion = direccion[0] + ':' + str(direccion[1])
        self.id = id
        self.hcriat = HandlerCriaturas()
        self.size = 1024
        # una vez creado le enviamos su id
        Protocolo.enviarId(socket, self.id)
        # funcionando!
        self.start()
        
    def run(self):
        while True:
            # recibimos los datos
            (sread, swrite, sexc) = select.select([self.socket], [], [])
            if sread:
                try:
                    paquete = self.socket.recv(self.size)
                except:
                    self.desconectar()
                    print "Desconexion forsoza"
                    break
                # si llego algo
                if paquete:
                    if DEBUG: print "Paquete recibido:", paquete
                    #procesamos
                    Protocolo(paquete, self.socket, self.id)
                # sino
                else:
                    # fin de conexion -> dejamos de escuchar al cliente
                    self.desconectar()
                    break
                
    def desconectar(self):
        self.socket.close()
        jug = self.hcriat.getCriaturaById(self.id)
        if jug:
            self.hcriat.desconectarJugador(self.id)
            Protocolo.enviarDesconectarCriatura(self.id)
        print "---> %s ha salido" % self.direccion